; BOOT SECTOR modified for ROM CP/M loading ; 512 bytes allocated space ORG $0000 CALL START ; "START" value will be changed to BIOS WBOOT (DF03) by WBOOT routine DEFB $80 ; IOBYTE | this is the standard CP/M system memory area SYSDRV DEFB $00 ; DSK BYTE | between 0000 and 0007 CALL $D106 ; BDOS | (BIOS WBOOT jump, IO Byte, DSK Byte, BDOS jump) ; SYSDRV is the default logical drive (system drive). ; This byte is adjusted by the BOOT code ; before running this BOOT SECTOR code COPRM DEFM "CP/M 2.2 Copyright (C) 1979 Digital Research, CoBra 53K BIOS, ROM Packaged 2013" DEFW $0A0D DEFM "User selected default system drive: " DRIVE DEFM "A:" DEFB $00 START: DI LD A,$40 OUT ($FE),A ; set O6 to 1 (VRAM CPU access) LD HL,$4000 LD DE,$4001 LD BC,$BFFF LD (HL),$00 LDIR ; erase 4000-FFFF (fill with zeros, black the CP/M screen) LD HL,$0200 LD DE,$C900 LD BC,$2200 ; *** changed for ROM LDIR ; CCP+BDOS+BIOS-1 LD HL,$2400 LD DE,$FB00 LD BC,$0300 LDIR ; BIOS-2 (DPH AREA) LD SP,$A000 ; stack at A000 LD HL,$0200 LD DE,$6008 LD B,$80 ; 80h loops next L00B3: PUSH BC ; <--- <--- <--- <--- <--- <--- <---| LD BC,$0010 ; | this copies 16 bytes LDIR ; copy 16 bytes from 0200 to 6008 | at once from: EX DE,HL ; \ | 0200 to 6008 this is a backup LD BC,$0010 ; \ DE is | 0210 to 6028 of CCP ADD HL,BC ; / incremented | 0220 to 6048 stored interleaved EX DE,HL ; / by 10h | ... in second VRAM page POP BC ; | ... DJNZ L00B3 ; ---> ---> ---> ---> ---> ---> --->| 09F0 to 6FE8 LD HL,$2700 ; *** changed for ROM LD DE,$5B00 ; copy 476h bytes from 2700 LD BC,$0476 ; to 5B00 (BLOCK#1) LDIR LD HL,$2B76 ; *** changed for ROM LD DE,$7B00 ; copy 4FFh bytes from 2B76 LD BC,$04FF ; to 7B00 (BLOCK#2) LDIR LD HL,$DF03 ; BIOS WBOOT address ... LD ($0001),HL ; ... stored in (0001-0002) CALL $E690 ; ; ########## MODIFICATIONS TO CP/M CODE ########## ; BDOS0D DEFB $3E ; \ DEFB $00 ; | this is a modified <- this will be nn in LD A,nn, nn=drv# at DD8D in BDOS DEFB $32 ; | code sequence to be DEFB $42 ; | replaced in BDOS#0D DEFB $D4 ; | to enable user selected DEFB $2F ; | default drive DEFB $80 ; / LD HL,BDOS0D LD DE,$DD8C LD BC,$07 LDIR ; replace code in BDOS routine #0D (Reset Disk System) LD A,$D9 ; ########### BIOS DPH area ########### LD ($FB00),A ; change XLT in DPH#0 in BIOS LD ($FB10),A ; change XLT in DPH#1 in BIOS LD ($FB40),A ; change XLT in DPH#4 in BIOS LD A,$CA LD ($FB0A),A ; change DPB in DPH#0 in BIOS LD ($FB1A),A ; change DPB in DPH#1 in BIOS LD ($FB4A),A ; change DPB in DPH#4 in BIOS LD ($DF59),A ; change DPB addr stored parameter in BIOS ; ########### BIOS SECTRAN fix for A:,B: to be 720K DSDD drives ########## LD HL,$0000 LD ($E11E),HL ; changes 2804="JR Z,$E124" to NOP NOP ; ########### BIOS BLOCK#1 fix for A:,B: to be the same as C:,D: ########## LD HL,$0000 LD ($5D35),HL ; changes 2808="JR Z,$5D3F" to NOP NOP LD ($5BA9),HL ; changes 2808="JR Z,$5BAD" to NOP NOP LD A,$18 LD ($5BC3),A ; ########### default drive ########### LD A,(SYSDRV) ; system logical drive, set from the BOOT code LD ($FDF8),A ; copy to FDF8 (first arg for 8272 command in routine $5CBE) LD HL,$FC04 ; HL=logical drive vector address (virtual drive E:) LD (HL),A ; (FC04)=system logical drive INC HL LD (HL),A ; (FC05)=system logical drive INC HL LD (HL),A ; (FC06)=system logical drive INC HL LD (HL),A ; (FC07)=system logical drive LD HL,$DD8D ; addr of default system drive# in modified BDOS function #0D (Reset Disk System) LD (HL),A ; default drive# changed LD HL,$DF51 ; crt. physical drv# in BIOS LD (HL),A LD HL,$DF5C ; crt. logical drv# in BIOS LD (HL),A ADD A,$41 LD (DRIVE),A ; update current system drive displayed in message LD A,$00 LD ($E0AC),A ; prevent DSK byte change if wrong logical disk login attempt ; ; ################################################ ; LD HL,$FD98 ; CTC interrupt table start address IM 2 LD A,H ; upper half of CTC interrupt table start address (FD)... LD I,A ; ...is stored in register I (see Z80 docs) LD A,L ; lower half of CTC interrupt table start address (98)... OUT ($E3),A ; ...is sent to CTC channel 0 ; MEANING: Interrupt Vector being used by all 4 channels!! ; Interrupt Vector = 10011cc0 where cc is the CTC channel. ; requesting the interrupt. So interrupt vector for ; CTC0 = FD98, CTC1 = FD9A, CTC2 = FD9C, CTC3 = FD9E LD A,$7F ; data for CTC0 on next line: set CTC0 to counter mode ; and disable CTC0 interrupts, time const. follows OUT ($E3),A LD A,$01 ; CTC0 time constant (one int. per one byte read)... OUT ($E3),A ; ...sent to CTC0 LD A,$7B ; data for CTC1+2 (disable int. no time const. follows)... OUT ($EB),A ; ...sent to CTC1... OUT ($F3),A ; ...and CTC2 LD A,$7F ; data for CTC3 (disable int. time const. follows)... OUT ($FB),A ; ...is sent to CTC3 LD A,$01 ; time constant for CTC3... OUT ($FB),A ; ...is sent to CTC3 LD A,(SYSDRV) ; system logical drive, set from the BOOT code AND $03 OR $30 ; set bits 4, 5 (30h = ASCII code for "0", 31h="1" ...) LD ($7F2D),A ; (7F2D) holds the "2" in "Insert disk E in drive 2:" LD HL,COPRM ; addr of copyright message CALL $5F3D ; print message LD A,$40 OUT ($FE),A ; set O6=1 (VRAM CPU access) - because O6 reset by print message above XOR A LD ($DF40),A CALL $5F62 ; erase 0008-3FF8 and jump to WBOOT